﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestCrawler.Html;
using TestGraph;
using TestGraph.Interfaces;
using System.Collections;

namespace TestCrawler
{
    public class Crawler
    {
        private IList<string> _visitedLinks;
        private IBasicGraph _siteMap;
        private IHtmlDoc _startPage;
        private Vertex _mainRoot;
        private string _url;

        public Crawler(string url)
        {
            _visitedLinks = new List<string>();
            _siteMap = new BasicGraph();
            _startPage = new HtmlDoc(url);
            _url = url;
        }

        internal void BuildSiteMap()
        {
            Queue<IHtmlDoc> qPages = new Queue<IHtmlDoc>();
            Queue<Vertex> qVertices = new Queue<Vertex>();

            _mainRoot = new Vertex(_startPage.Url);
            Vertex root = _mainRoot;
            Vertex leaf = null;
            _siteMap.AddVertex(root);
            qVertices.Enqueue(root);
            qPages.Enqueue(_startPage);

            Console.WriteLine(root.Name); // trace
            while (qPages.Count > 0)
            {
                while ((leaf = GetNextUnvisited(qPages.Peek().GetAllLinks())) != null)
                {
                    Console.WriteLine(leaf.Name); // trace
                    _siteMap.AddVertex(leaf);
                    _siteMap.AddEdge(root, leaf);
                    qVertices.Enqueue(leaf);
                    qPages.Enqueue(new HtmlDoc(leaf.Name));
                } // end while

                root = qVertices.Dequeue();
                qPages.Dequeue();

            } // end while
        }

        private Vertex GetNextUnvisited(IList<string> links)
        {
            Vertex v = null;
            int index = 0;
            bool foundUnvisited = false;
            while (!foundUnvisited && index < links.Count)
            {
                if (!_visitedLinks.Contains(links[index]))
                {
                    _visitedLinks.Add(links[index]);
                    v = new Vertex(links[index]);
                    foundUnvisited = true;
                } // end if
                index++;
            } // end while
            return v;
        }

        public void GraphTraversal()
        {
            Console.WriteLine("*** Dfs ***");
            IList list = _siteMap.DfsIterative(_mainRoot);
            foreach (Vertex v in list)
            {
                Console.WriteLine(v.Name);
            } // end foreach

            Console.WriteLine();

            Console.WriteLine("*** Bfs ***");
            list = _siteMap.BfsIterative(_mainRoot);
            foreach (Vertex v in list)
            {
                Console.WriteLine(v.Name);
            } 
        }
    }
}
